package com.ziiwee.reduce.rest.auto;

import com.ziiwee.reduce.commons.utils.ExportUtil;
import com.ziiwee.reduce.commons.utils.StringUtil;
import com.ziiwee.reduce.rest.ResourceService;
import com.ziiwee.reduce.rest.ResourceServiceException;
import com.ziiwee.reduce.rest.utils.RestUtil;
import org.springframework.core.ResolvableType;
import org.springframework.util.Assert;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ziiwee
 * @date 2020/8/18
 */
public class DefaultResourceMapping implements ResourceMapping {

    private final Map<String, ResourceInfo> mapping = new HashMap<>();

    @Override
    public ResourceInfo get(String name) {
        return mapping.get(name);
    }

    @Override
    public Collection<ResourceInfo> getAll() {
        return mapping.values();
    }

    @Override
    public void register(ResourceInfo resourceInfo) {
        if (ExportUtil.isExport(resourceInfo.getType()) || ExportUtil.isExport(resourceInfo.getService().getClass())) {
            mapping.put(resourceInfo.getName(), resourceInfo);
        }
    }

    @Override
    public void register(ResourceService<?, ?> service) {
        try {
            List<ResolvableType> args = RestUtil.getTypeArgsByInstance(service, ResourceService.class);
            ResourceInfoModel model = new ResourceInfoModel();
            Class<?> type = args.get(0).resolve();
            Class<?> idType = args.get(1).resolve();
            Assert.notNull(type, "无法获取 Resource 类型");
            Assert.notNull(idType, "无法获取 Resource 的 Id 类型");
            String name = StringUtil.firstToLowerCase(type.getSimpleName());
            model.setName(name);
            model.setType(type);
            model.setIdType(idType);
            model.setService(service);
            register(model);
        } catch (Exception e) {
            throw new ResourceServiceException(String.format("不符合要求的 ResourceService [%s] : %s", service.getClass(), e.getMessage()), e);
        }
    }

}
